//
//  YCTitleCollectionView.m
//  TitleContent
//
//  Created by 唐可雄 on 2019/7/18.
//  Copyright © 2019 swustyc. All rights reserved.
//

#import "YCTitleCollectionView.h"

#import <Tool/Tool.h>

#import "YCTextTitleViewCell.h"
#define Str_YCTextTitleViewCell @"YCTextTitleViewCell"
#define Str_YCCustomTitleViewCell @"YCCustomTitleViewCell"

@interface YCTitleCollectionView ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> {
    NSUInteger _selectedIndex;
}

@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) UIView *lineView;

@end

@implementation YCTitleCollectionView

#pragma mark - Layout

- (void)layoutSubviews {
    CGFloat oldWith = self.collectionView.frame.size.width;
    
    [super layoutSubviews];
    
    if (oldWith != self.collectionView.frame.size.width) {
        self.collectionView.collectionViewLayout = [self createLayout];
    }
    
    [self updateLineView];
}

- (YCCollectionViewFlowLayout *)createLayout {
    YCCollectionViewFlowLayout *flowLayout = [[YCCollectionViewFlowLayout alloc] init];
    flowLayout.minimumInteritemSpacing = self.config.collectionViewCellSpace;
    flowLayout.alignment = self.config.collectionViewCellAlignment;
    flowLayout.originEdgeInsets = self.config.collectionViewEdgeInsets;
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    return flowLayout;
}

#pragma mark - Super-Sub View

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    if (newSuperview) {
        [self configView];
    }
}

#pragma mark - View Config

- (void)configView {
    UIButton *rightBtn = nil;
    if ([self.dataSource respondsToSelector:@selector(rightButtonInTitleCollectionView:)]) {
        rightBtn = [self.dataSource rightButtonInTitleCollectionView:self];
    }
    [self addRightButton:rightBtn];
    [self addCollectionView:rightBtn];
    [self addLineView];
    [self addSeparatorView];
}

- (void)addCollectionView:(UIButton *)rightBtn {
    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[self createLayout]];
    self.collectionView.showsHorizontalScrollIndicator = NO;
    self.collectionView.showsVerticalScrollIndicator = NO;
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;
    self.collectionView.backgroundColor = self.config.titleViewBackgroundColor;
    if (self.config.collectionViewCellStyle == YCCollectionViewCellStyleText) {
        [self.collectionView registerClass:[YCTextTitleViewCell class] forCellWithReuseIdentifier:Str_YCTextTitleViewCell];
    } else {
        [self.collectionView registerClass:[self.dataSource customCellClassInTitleCollectionView:self] forCellWithReuseIdentifier:Str_YCCustomTitleViewCell];
    }
    self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:self.collectionView];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.collectionView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.collectionView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
    if (rightBtn) {
        [self addConstraint:[NSLayoutConstraint constraintWithItem:self.collectionView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:rightBtn attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
    } else {
        [self addConstraint:[NSLayoutConstraint constraintWithItem:self.collectionView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
    }
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.collectionView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
}

- (void)addLineView {
    self.lineView = [[UIView alloc] init];
    self.lineView.backgroundColor = self.config.lineViewBackgroundColor;
    if (self.config.lineViewShape == YCLineViewShapeRoundRect) {
        self.lineView.layer.cornerRadius = self.config.lineViewHeight / 2.f;
    } else {
        self.lineView.layer.cornerRadius = 0;
    }
    self.lineView.layer.masksToBounds = YES;
    self.lineView.hidden = self.config.lineViewHidden;
    [self.collectionView addSubview:self.lineView];
}

- (void)addRightButton:(UIButton *)rightBtn {
    if (rightBtn) {
        rightBtn.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:rightBtn];
        [rightBtn addConstraint:[NSLayoutConstraint constraintWithItem:rightBtn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:rightBtn.bounds.size.width]];
        [rightBtn addConstraint:[NSLayoutConstraint constraintWithItem:rightBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:rightBtn.bounds.size.height]];
        [self addConstraint:[NSLayoutConstraint constraintWithItem:rightBtn attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
        [self addConstraint:[NSLayoutConstraint constraintWithItem:rightBtn attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    }
}

#pragma mark - Select

- (void)setSelectedIndex:(NSUInteger)selectedIndex {
    NSUInteger oldIndex = _selectedIndex;
    _selectedIndex = selectedIndex;
    
    [UIView performWithoutAnimation:^{
        if (oldIndex == self->_selectedIndex) {
            [self.collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:oldIndex inSection:0]]];
        } else {
            [self.collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:oldIndex inSection:0], [NSIndexPath indexPathForRow:self->_selectedIndex inSection:0]]];
        }
    }];
    
    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:_selectedIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
    
    [self updateLineView];
}

#pragma mark - UICollectionViewDataSource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self.dataSource numberOfTitlesInTitleView:self];;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (self.config.collectionViewCellStyle == YCCollectionViewCellStyleText) {
        YCTextTitleViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:Str_YCTextTitleViewCell forIndexPath:indexPath];
        cell.config = self.config;
        cell.textLabel.text = [self.dataSource titleCollectionView:self titleAtIndex:indexPath.row];
        [cell configWithSelected:_selectedIndex == indexPath.row];
        return cell;
    } else {
        YCTitleViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:Str_YCCustomTitleViewCell forIndexPath:indexPath];
        cell.config = self.config;
        [self.dataSource titleCollectionView:self configCellAtIndex:indexPath.row];
        [cell configWithSelected:_selectedIndex== indexPath.row];
        return cell;
    }
}

#pragma mark - UICollectionViewDelegateFlowLayout

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [self sizeForCellAtIndex:indexPath.row];
}

#pragma mark - UICollectionViewDelegate

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    if (_selectedIndex != indexPath.row) {
        [self setSelectedIndex:indexPath.row];
        if ([self.delegate respondsToSelector:@selector(titleView:didSelectAtIndex:)]) {
            [self.delegate titleView:self didSelectAtIndex:_selectedIndex];
        }
    }
}

#pragma mark - Line View

- (CGRect)caculateLineViewFrameAtIndex:(NSUInteger)index {
    UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
    CGFloat x = 0;
    CGFloat width = 0;
    if (cell) {
        if (self.config.lineViewWidth == YCLineViewWidthAuto) {
            width = cell.frame.size.width;
            x = cell.frame.size.width > 0 ? CGRectGetMidX(cell.frame) - width / 2 : 0;
        } else {
            width = self.config.lineViewWidth;
            x = cell.frame.size.width > 0 ? CGRectGetMidX(cell.frame) - width / 2 : 0;
        }
    }
    
    CGFloat y = 0;
    if (self.config.lineViewAlignment == YCLineViewAlignmentTop) {
        y = 0;
    } else if (self.config.lineViewAlignment == YCLineViewAlignmentCenter) {
        y = CGRectGetMidY(cell.frame) - self.config.lineViewHeight / 2;
    } else {
        y = self.bounds.size.height - self.config.lineViewHeight - self.config.separatorViewHeight;
    }
    return CGRectMake(x, y, width, self.config.lineViewHeight);
}

- (void)updateLineView {
    self.lineView.frame = [self caculateLineViewFrameAtIndex:_selectedIndex];
}

- (void)showLineViewTransitionFrom:(CGRect)rectFrom to:(CGRect)rectTo transitionType:(YCLineViewTransitionType)transitionType progress:(CGFloat)progress {
    switch (transitionType) {
        case YCLineViewTransitionTypeNone:
            
            break;
        case YCLineViewTransitionTypeTranslation:
        {
            CGFloat distance = CGRectGetMidX(rectTo) - CGRectGetMidX(rectFrom);
            CGFloat centerX = CGRectGetMidX(rectFrom) + progress * distance;
            CGFloat width = rectFrom.size.width + (rectTo.size.width - rectFrom.size.width) * progress;
            self.lineView.frame = CGRectMake(centerX - width / 2, rectFrom.origin.y, width, rectFrom.size.height);
        }
            break;
        case YCLineViewTransitionTypePull:
        {
            if (rectTo.origin.x > rectFrom.origin.x) {
                if (progress < 0.5) {
                    CGFloat distance = (CGRectGetMaxX(rectTo) - CGRectGetMaxX(rectFrom)) * 2 * progress;
                    self.lineView.frame = CGRectMake(rectFrom.origin.x, rectFrom.origin.y, rectFrom.size.width + distance, rectFrom.size.height);
                } else {
                    CGFloat distance = (rectTo.origin.x - rectFrom.origin.x) * 2 * (1 - progress);
                    self.lineView.frame = CGRectMake(rectTo.origin.x - distance, rectFrom.origin.y, rectTo.size.width + distance, rectFrom.size.height);
                }
            } else {
                if (progress < 0.5) {
                    CGFloat distance = (rectFrom.origin.x - rectTo.origin.x) * 2 * progress;
                    self.lineView.frame = CGRectMake(rectFrom.origin.x - distance, rectFrom.origin.y, rectFrom.size.width + distance, rectFrom.size.height);
                } else {
                    CGFloat distance = (CGRectGetMaxX(rectFrom) - CGRectGetMaxX(rectTo)) * 2 * (1 - progress);
                    self.lineView.frame = CGRectMake(rectTo.origin.x, rectFrom.origin.y, rectTo.size.width + distance, rectFrom.size.height);
                }
            }
        }
            break;
        default:
            break;
    }
}

#pragma mark - Load

- (void)reloadData {
    [self.collectionView reloadData];
}

#pragma mark - Other

- (CGSize)sizeForCellAtIndex:(NSUInteger)index {
    CGSize size = CGSizeZero;
    
    if (self.config.titleCollectionViewCellWidth > 0) {
        size.width = self.config.titleCollectionViewCellWidth;
    }
    
    if (self.config.collectionViewCellStyle == YCCollectionViewCellStyleText) {
        UILabel *label = [[UILabel alloc] init];
        label.numberOfLines = 1;
        label.lineBreakMode = NSLineBreakByWordWrapping;
        label.textAlignment = NSTextAlignmentCenter;
        label.text = [self.dataSource titleCollectionView:self titleAtIndex:index];
        label.font = _selectedIndex==index ? self.config.textFontSelected : self.config.textFontUnselected;
        size.width = ceil([label sizeThatFits:self.collectionView.bounds.size].width) + 1;
    }
    
    size.height = self.collectionView.bounds.size.height - self.config.collectionViewEdgeInsets.top - self.config.collectionViewEdgeInsets.bottom;
    
    return size;
}

- (void)transitionToTargetIndex:(NSUInteger)targetIndex progress:(CGFloat)progress {
    YCTitleViewCell *cellCurrent = (YCTitleViewCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:_selectedIndex inSection:0]];
    [cellCurrent showUnselectTransitionWithProgress:progress];
    
    YCTitleViewCell *cellTarget = (YCTitleViewCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:targetIndex inSection:0]];
    [cellTarget showSelectTransitionWithProgress:progress];
    
    [self showLineViewTransitionFrom:[self caculateLineViewFrameAtIndex:_selectedIndex] to:[self caculateLineViewFrameAtIndex:targetIndex] transitionType:self.config.lineViewTransitionType progress:progress];
}

@end
